home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 32 / Amiga Format AFCD32 (Nov 1998, Issue 117).iso / -seriously_amiga- / programming / c / mesa-2.6 / src-glu / quadric.c < prev    next >
C/C++ Source or Header  |  1998-08-10  |  21KB  |  804 lines

  1. /* $Id: quadric.c,v 1.13 1998/02/07 14:28:34 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.6
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * quadric.c
  26.  *
  27.  * Version 1.0  27 Jun 1998
  28.  * by Jarno van der Linden
  29.  * jarno@kcbbs.gen.nz
  30.  *
  31.  * File created from quadric.c ver 1.13 and glu.h ver 1.9 using GenProtos
  32.  *
  33.  */
  34.  
  35.  
  36. /* TODO:
  37.  *   texture coordinate support
  38.  *   flip normals according to orientation
  39.  *   there's still some inside/outside orientation bugs in possibly all
  40.  *     but the sphere function
  41.  */
  42.  
  43.  
  44. #ifdef PC_HEADER
  45. #include "all.h"
  46. #else
  47. #include <math.h>
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include "gluP.h"
  51. #endif
  52.  
  53.  
  54.  
  55. #ifndef M_PI
  56. #  define M_PI (3.1415926)
  57. #endif
  58.  
  59.  
  60. /*
  61.  * Convert degrees to radians:
  62.  */
  63. #define DEG_TO_RAD(A)   ((A)*(M_PI/180.0))
  64.  
  65.  
  66. /*
  67.  * Sin and Cos for degree angles:
  68.  */
  69. #define SIND( A )   sin( (A)*(M_PI/180.0) )
  70. #define COSD( A)    cos( (A)*(M_PI/180.0) )
  71.  
  72.  
  73. /*
  74.  * Texture coordinates if texture flag is set
  75.  */
  76. #define TXTR_COORD(x,y)    if (qobj->TextureFlag) glTexCoord2f(x,y);
  77.  
  78.  
  79.  
  80. struct GLUquadricObj {
  81.     GLenum    DrawStyle;        /* GLU_FILL, LINE, SILHOUETTE, or POINT */
  82.     GLenum Orientation;        /* GLU_INSIDE or GLU_OUTSIDE */
  83.     GLboolean TextureFlag;        /* Generate texture coords? */
  84.     GLenum Normals;        /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
  85.     void (CALLBACK *ErrorFunc)(GLenum err);    /* Error handler callback function */
  86. };
  87.  
  88.  
  89.  
  90. /*
  91.  * Process a GLU error.
  92.  */
  93. static void quadric_error( GLUquadricObj *qobj, GLenum error, const char *msg )
  94. {
  95.    /* Call the error call back function if any */
  96.    if (qobj->ErrorFunc) {
  97.       (*qobj->ErrorFunc)( error );
  98.    }
  99.    /* Print a message to stdout if MESA_DEBUG variable is defined */
  100.    if (getenv("MESA_DEBUG")) {
  101.       fprintf(stderr,"GLUError: %s: %s\n", gluErrorString(error), msg );
  102.    }
  103. }
  104.  
  105.  
  106.  
  107. __asm __saveds GLUquadricObj* APIENTRY gluNewQuadric( void )
  108. {
  109.    GLUquadricObj *q;
  110.  
  111.    q = (GLUquadricObj *) malloc( sizeof(struct GLUquadricObj) );
  112.    if (q) {
  113.       q->DrawStyle = GLU_FILL;
  114.       q->Orientation = GLU_OUTSIDE;
  115.       q->TextureFlag = GL_FALSE;
  116.       q->Normals = GLU_SMOOTH;
  117.       q->ErrorFunc = NULL;
  118.    }
  119.    return q;
  120. }
  121.  
  122.  
  123.  
  124. __asm __saveds void APIENTRY gluDeleteQuadric( register __a0 GLUquadricObj *state )
  125. {
  126.    if (state) {
  127.       free( (void *) state );
  128.    }
  129. }
  130.  
  131.  
  132.  
  133. /*
  134.  * Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
  135.  * or GLU_POINT.
  136.  */
  137. __asm __saveds void APIENTRY gluQuadricDrawStyle( register __a0 GLUquadricObj *quadObject, register __d0 GLenum drawStyle )
  138. {
  139.    if (quadObject && (drawStyle==GLU_FILL || drawStyle==GLU_LINE
  140.            || drawStyle==GLU_SILHOUETTE || drawStyle==GLU_POINT)) {
  141.       quadObject->DrawStyle = drawStyle;
  142.    }
  143.    else {
  144.       quadric_error( quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle" );
  145.    }
  146. }
  147.  
  148.  
  149.  
  150. /*
  151.  * Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
  152.  */
  153. __asm __saveds void APIENTRY gluQuadricOrientation( register __a0 GLUquadricObj *quadObject,
  154.                                                     register __d0 GLenum orientation )
  155. {
  156.    if (quadObject && (orientation==GLU_INSIDE || orientation==GLU_OUTSIDE)) {
  157.       quadObject->Orientation = orientation;
  158.    }
  159.    else {
  160.       quadric_error( quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation" );
  161.    }
  162. }
  163.  
  164.  
  165.  
  166. /*
  167.  * Set the error handler callback function.
  168.  */
  169. __asm __saveds void APIENTRY gluQuadricCallback( register __a0 GLUquadricObj *qobj,
  170.                                                  register __d0 GLenum which, register __a1 void (CALLBACK *fn)() )
  171. {
  172.    /*
  173.     * UGH, this is a mess!  I thought ANSI was a standard.
  174.     */
  175.    if (qobj && which==GLU_ERROR) {
  176. #ifdef __CYGWIN32__
  177.       qobj->ErrorFunc = (void(*)(int))fn;
  178. #elif defined(_WIN32)
  179.       qobj->ErrorFunc = (void(CALLBACK*)(int))fn;
  180. #elif defined(__STORM__)
  181.       qobj->ErrorFunc = (void(CALLBACK*)(GLenum))fn;
  182. #else
  183.       qobj->ErrorFunc = (void(CALLBACK*)())fn;
  184. #endif
  185.    }
  186. }
  187.  
  188.  
  189. __asm __saveds void APIENTRY gluQuadricNormals( register __a0 GLUquadricObj *quadObject, register __d0 GLenum normals )
  190. {
  191.    if (quadObject
  192.          && (normals==GLU_NONE || normals==GLU_FLAT || normals==GLU_SMOOTH)) {
  193.       quadObject->Normals = normals;
  194.    }
  195. }
  196.  
  197.  
  198. __asm __saveds void APIENTRY gluQuadricTexture( register __a0 GLUquadricObj *quadObject,
  199.                                                 register __d0 GLboolean textureCoords )
  200. {
  201.    if (quadObject) {
  202.       quadObject->TextureFlag = textureCoords;
  203.    }
  204. }
  205.  
  206.  
  207.  
  208.  
  209. /*
  210.  * Call glNormal3f after scaling normal to unit length.
  211.  */
  212. static void normal3f( GLfloat x, GLfloat y, GLfloat z )
  213. {
  214.    GLdouble mag;
  215.  
  216.    mag = sqrt( x*x + y*y + z*z );
  217.    if (mag>0.00001F) {
  218.       x /= mag;
  219.       y /= mag;
  220.       z /= mag;
  221.    }
  222.    glNormal3f( x, y, z );
  223. }
  224.  
  225.  
  226.  
  227. __asm __saveds void APIENTRY gluCylinderA(register __a0 void *vargs)
  228. {
  229.     struct gluCylinderArgs {
  230.         GLUquadricObj *qobj;
  231.         GLdouble baseRadius;
  232.         GLdouble topRadius;
  233.         GLdouble height;
  234.         GLint slices;
  235.         GLint stacks;
  236.     } *args;
  237.  
  238.     args = (struct gluCylinderArgs *)vargs;
  239.  
  240.     gluCylinder(args->qobj, args->baseRadius, args->topRadius, args->height, args->slices, args->stacks);
  241. }
  242.  
  243.  
  244. __asm __saveds void APIENTRY gluCylinder( register __a0 GLUquadricObj *qobj,
  245.                                           register __fp0 GLdouble baseRadius, register __fp1 GLdouble topRadius,
  246.                                           register __fp2 GLdouble height, register __d0 GLint slices, register __d1 GLint stacks )
  247. {
  248.    GLdouble da, r, dr, dz;
  249.    GLfloat x, y, z, nz, nsign;
  250.    GLint i, j;
  251.  
  252.    if (qobj->Orientation==GLU_INSIDE) {
  253.       nsign = -1.0;
  254.    }
  255.    else {
  256.       nsign = 1.0;
  257.    }
  258.  
  259.    da = 2.0*M_PI / slices;
  260.    dr = (topRadius-baseRadius) / stacks;
  261.    dz = height / stacks;
  262.    nz = (baseRadius-topRadius) / height;  /* Z component of normal vectors */
  263.  
  264.    if (qobj->DrawStyle==GLU_POINT) {
  265.       glBegin( GL_POINTS );
  266.       for (i=0;i<slices;i++) {
  267.      x = cos(i*da);
  268.      y = sin(i*da);
  269.      normal3f( x*nsign, y*nsign, nz*nsign );
  270.  
  271.      z = 0.0;
  272.      r = baseRadius;
  273.      for (j=0;j<=stacks;j++) {
  274.         glVertex3f( x*r, y*r, z );
  275.         z += dz;
  276.         r += dr;
  277.      }
  278.       }
  279.       glEnd();
  280.    }
  281.    else if (qobj->DrawStyle==GLU_LINE || qobj->DrawStyle==GLU_SILHOUETTE) {
  282.       /* Draw rings */
  283.       if (qobj->DrawStyle==GLU_LINE) {
  284.      z = 0.0;
  285.      r = baseRadius;
  286.      for (j=0;j<=stacks;j++) {
  287.         glBegin( GL_LINE_LOOP );
  288.         for (i=0;i<slices;i++) {
  289.            x = cos(i*da);
  290.            y = sin(i*da);
  291.            normal3f( x*nsign, y*nsign, nz*nsign );
  292.            glVertex3f( x*r, y*r, z );
  293.         }
  294.         glEnd();
  295.         z += dz;
  296.         r += dr;
  297.      }
  298.       }
  299.       else {
  300.      /* draw one ring at each end */
  301.      if (baseRadius!=0.0) {
  302.         glBegin( GL_LINE_LOOP );
  303.         for (i=0;i<slices;i++) {
  304.            x = cos(i*da);
  305.            y = sin(i*da);
  306.            normal3f( x*nsign, y*nsign, nz*nsign );
  307.            glVertex3f( x*baseRadius, y*baseRadius, 0.0 );
  308.         }
  309.         glEnd();
  310.         glBegin( GL_LINE_LOOP );
  311.         for (i=0;i<slices;i++) {
  312.            x = cos(i*da);
  313.            y = sin(i*da);
  314.            normal3f( x*nsign, y*nsign, nz*nsign );
  315.            glVertex3f( x*topRadius, y*topRadius, height );
  316.         }
  317.         glEnd();
  318.      }
  319.       }
  320.       /* draw length lines */
  321.       glBegin( GL_LINES );
  322.       for (i=0;i<slices;i++) {
  323.      x = cos(i*da);
  324.      y = sin(i*da);
  325.      normal3f( x*nsign, y*nsign, nz*nsign );
  326.      glVertex3f( x*baseRadius, y*baseRadius, 0.0 );
  327.      glVertex3f( x*topRadius, y*topRadius, height );
  328.       }
  329.       glEnd();
  330.    }
  331.    else if (qobj->DrawStyle==GLU_FILL) {
  332.       GLfloat du = 1.0 / slices;
  333.       GLfloat dv = 1.0 / stacks;
  334.       GLfloat tcx = 0.0, tcy = 0.0;
  335.  
  336.       for (i=0;i<slices;i++) {
  337.      GLfloat x1 = -sin(i*da);
  338.      GLfloat y1 = cos(i*da);
  339.      GLfloat x2 = -sin((i+1)*da);
  340.      GLfloat y2 = cos((i+1)*da);
  341.      z = 0.0;
  342.      r = baseRadius;
  343.      tcy = 0.0;
  344.      glBegin( GL_QUAD_STRIP );
  345.      for (j=0;j<=stacks;j++) {
  346.         if (nsign==1.0) {
  347.            normal3f( x1*nsign, y1*nsign, nz*nsign );
  348.            TXTR_COORD(tcx, tcy);
  349.            glVertex3f( x1*r, y1*r, z );
  350.            normal3f( x2*nsign, y2*nsign, nz*nsign );
  351.            TXTR_COORD(tcx+du, tcy);
  352.            glVertex3f( x2*r, y2*r, z );
  353.         }
  354.         else {
  355.            normal3f( x2*nsign, y2*nsign, nz*nsign );
  356.            TXTR_COORD(tcx, tcy);
  357.            glVertex3f( x2*r, y2*r, z );
  358.            normal3f( x1*nsign, y1*nsign, nz*nsign );
  359.            TXTR_COORD(tcx+du, tcy);
  360.            glVertex3f( x1*r, y1*r, z );
  361.         }
  362.         z += dz;
  363.         r += dr;
  364.         tcy += dv;
  365.      }
  366.      glEnd();
  367.      tcx += du;
  368.       }
  369.    }
  370. }
  371.  
  372.  
  373.  
  374.  
  375.  
  376. __asm __saveds void APIENTRY gluSphere( register __a0 GLUquadricObj *qobj,
  377.                                         register __fp0 GLdouble radius, register __d0 GLint slices, register __d1 GLint stacks )
  378. {
  379.    GLfloat rho, drho, theta, dtheta;
  380.    GLfloat x, y, z;
  381.    GLfloat s, t, ds, dt;
  382.    GLint i, j, imin, imax;
  383.    GLboolean normals;
  384.    GLfloat nsign;
  385.  
  386.    if (qobj->Normals==GLU_NONE) {
  387.       normals = GL_FALSE;
  388.    }
  389.    else {
  390.       normals = GL_TRUE;
  391.    }
  392.    if (qobj->Orientation==GLU_INSIDE) {
  393.       nsign = -1.0;
  394.    }
  395.    else {
  396.       nsign = 1.0;
  397.    }
  398.  
  399.    drho = M_PI / (GLfloat) stacks;
  400.    dtheta = 2.0 * M_PI / (GLfloat) slices;
  401.  
  402.    /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
  403.    /* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
  404.    /* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
  405.  
  406.    if (qobj->DrawStyle==GLU_FILL) {
  407.      if (!qobj->TextureFlag) {
  408.       /* draw +Z end as a triangle fan */
  409.       glBegin( GL_TRIANGLE_FAN );
  410.       glNormal3f( 0.0, 0.0, 1.0 );
  411.       TXTR_COORD(0.5,1.0);
  412.       glVertex3f( 0.0, 0.0, nsign * radius );
  413.       for (j=0;j<=slices;j++) {
  414.      theta = (j==slices) ? 0.0 : j * dtheta;
  415.      x = -sin(theta) * sin(drho);
  416.      y = cos(theta) * sin(drho);
  417.      z = nsign * cos(drho);
  418.      if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  419.      glVertex3f( x*radius, y*radius, z*radius );
  420.       }
  421.       glEnd();
  422.      }
  423.  
  424.       ds = 1.0 / slices;
  425.       dt = 1.0 / stacks;
  426.       t = 1.0;  /* because loop now runs from 0 */
  427.       if (qobj->TextureFlag) {
  428.         imin = 0;
  429.         imax = stacks;
  430.       }
  431.       else {
  432.         imin = 1;
  433.         imax = stacks-1;
  434.       }
  435.  
  436.       /* draw intermediate stacks as quad strips */
  437.       for (i=imin;i<imax;i++) {
  438.      rho = i * drho;
  439.      glBegin( GL_QUAD_STRIP );
  440.          s = 0.0;
  441.      for (j=0;j<=slices;j++) {
  442.         theta = (j==slices) ? 0.0 : j * dtheta;
  443.         x = -sin(theta) * sin(rho);
  444.         y = cos(theta) * sin(rho);
  445.         z = nsign * cos(rho);
  446.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  447.         TXTR_COORD(s,t);
  448.         glVertex3f( x*radius, y*radius, z*radius );
  449.         x = -sin(theta) * sin(rho+drho);
  450.         y = cos(theta) * sin(rho+drho);
  451.         z = nsign * cos(rho+drho);
  452.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  453.         TXTR_COORD(s,t-dt);
  454.             s += ds;
  455.         glVertex3f( x*radius, y*radius, z*radius );
  456.      }
  457.      glEnd();
  458.      t -= dt;
  459.       }
  460.  
  461.      if (!qobj->TextureFlag) {
  462.       /* draw -Z end as a triangle fan */
  463.       glBegin( GL_TRIANGLE_FAN );
  464.       glNormal3f( 0.0, 0.0, -1.0 );
  465.       TXTR_COORD(0.5,0.0);
  466.       glVertex3f( 0.0, 0.0, -radius*nsign );
  467.       rho = M_PI - drho;
  468.       s = 1.0;
  469.       t = dt;
  470.       for (j=slices;j>=0;j--) {
  471.      theta = (j==slices) ? 0.0 : j * dtheta;
  472.      x = -sin(theta) * sin(rho);
  473.      y = cos(theta) * sin(rho);
  474.      z = nsign * cos(rho);
  475.      if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  476.      TXTR_COORD(s,t);
  477.          s -= ds;
  478.      glVertex3f( x*radius, y*radius, z*radius );
  479.       }
  480.       glEnd();
  481.      }
  482.    }
  483.    else if (qobj->DrawStyle==GLU_LINE || qobj->DrawStyle==GLU_SILHOUETTE) {
  484.       /* draw stack lines */
  485.       for (i=1;i<stacks;i++) {  /* stack line at i==stacks-1 was missing here */
  486.      rho = i * drho;
  487.      glBegin( GL_LINE_LOOP );
  488.      for (j=0;j<slices;j++) {
  489.         theta = j * dtheta;
  490.         x = cos(theta) * sin(rho);
  491.         y = sin(theta) * sin(rho);
  492.         z = cos(rho);
  493.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  494.         glVertex3f( x*radius, y*radius, z*radius );
  495.      }
  496.      glEnd();
  497.       }
  498.       /* draw slice lines */
  499.       for (j=0;j<slices;j++) {
  500.      theta = j * dtheta;
  501.      glBegin( GL_LINE_STRIP );
  502.      for (i=0;i<=stacks;i++) {
  503.         rho = i * drho;
  504.         x = cos(theta) * sin(rho);
  505.         y = sin(theta) * sin(rho);
  506.         z = cos(rho);
  507.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  508.         glVertex3f( x*radius, y*radius, z*radius );
  509.      }
  510.      glEnd();
  511.       }
  512.    }
  513.    else if (qobj->DrawStyle==GLU_POINT) {
  514.       /* top and bottom-most points */
  515.       glBegin( GL_POINTS );
  516.       if (normals)  glNormal3f( 0.0, 0.0, nsign );
  517.       glVertex3d( 0.0, 0.0, radius );
  518.       if (normals)  glNormal3f( 0.0, 0.0, -nsign );
  519.       glVertex3d( 0.0, 0.0, -radius );
  520.  
  521.       /* loop over stacks */
  522.       for (i=1;i<stacks-1;i++) {
  523.      rho = i * drho;
  524.      for (j=0;j<slices;j++) {
  525.         theta = j * dtheta;
  526.         x = cos(theta) * sin(rho);
  527.         y = sin(theta) * sin(rho);
  528.         z = cos(rho);
  529.         if (normals)  glNormal3f( x*nsign, y*nsign, z*nsign );
  530.         glVertex3f( x*radius, y*radius, z*radius );
  531.      }
  532.       }
  533.       glEnd();
  534.    }
  535.  
  536. }
  537.  
  538.  
  539.  
  540. __asm __saveds void APIENTRY gluDisk( register __a0 GLUquadricObj *qobj,
  541.                                       register __fp0 GLdouble innerRadius, register __fp1 GLdouble outerRadius,
  542.                                       register __d0 GLint slices, register __d1 GLint loops )
  543. {
  544.    GLdouble a, da;
  545.    GLfloat r, dr;
  546.    GLfloat x, y;
  547.    GLfloat r1, r2, dtc;
  548.    GLint s, l;
  549.  
  550.    /* Normal vectors */
  551.    if (qobj->Normals!=GLU_NONE) {
  552.       if (qobj->Orientation==GLU_OUTSIDE) {
  553.      glNormal3f( 0.0, 0.0, +1.0 );
  554.       }
  555.       else {
  556.      glNormal3f( 0.0, 0.0, -1.0 );
  557.       }
  558.    }
  559.  
  560.    da = 2.0*M_PI / slices;
  561.    dr = (outerRadius-innerRadius) / (GLfloat) loops;
  562.  
  563.    /* texture of a gluDisk is a cut out of the texture unit square */
  564.    /* x, y in [-outerRadius, +outerRadius]; s, t in [0, 1] (linear mapping) */
  565.    dtc = 2.0f * outerRadius;
  566.  
  567.    switch (qobj->DrawStyle) {
  568.       case GLU_FILL:
  569.      {
  570.          GLfloat sa,ca;
  571.          r1 = innerRadius;
  572.          for (l=0;l<loops;l++) {
  573.         r2 = r1 + dr;
  574.         if (qobj->Orientation==GLU_OUTSIDE) {
  575.            glBegin( GL_QUAD_STRIP );
  576.            for (s=0;s<=slices;s++) {
  577.           if (s==slices) a = 0.0;
  578.           else  a = s * da;
  579.           sa = sin(a); ca = cos(a);
  580.                   TXTR_COORD(0.5+sa*r2/dtc,0.5+ca*r2/dtc);
  581.                   glVertex2f( r2*sa, r2*ca );
  582.                   TXTR_COORD(0.5+sa*r1/dtc,0.5+ca*r1/dtc);
  583.                   glVertex2f( r1*sa, r1*ca );
  584.            }
  585.            glEnd();
  586.         }
  587.         else {
  588.            glBegin( GL_QUAD_STRIP );
  589.            for (s=slices;s>=0;s--) {
  590.           if (s==slices) a = 0.0;
  591.           else  a = s * da;
  592.           sa = sin(a); ca = cos(a);
  593.                   TXTR_COORD(0.5-sa*r2/dtc,0.5+ca*r2/dtc);
  594.                   glVertex2f( r2*sa, r2*ca );
  595.                   TXTR_COORD(0.5-sa*r1/dtc,0.5+ca*r1/dtc);
  596.                   glVertex2f( r1*sa, r1*ca );
  597.            }
  598.            glEnd();
  599.         }
  600.         r1 = r2;
  601.      }
  602.          }
  603.          break;
  604.       case GLU_LINE:
  605.      /* draw rings */
  606.      for (r=innerRadius; r<=outerRadius; r+=dr) {
  607.         glBegin( GL_LINE_LOOP );
  608.         for (a=0.0; a<2.0*M_PI; a+=da) {
  609.            glVertex2f( r*sin(a), r*cos(a) );
  610.         }
  611.         glEnd();
  612.      }
  613.      /* draw spokes */
  614.      for (a=0.0; a<2.0*M_PI; a+=da) {
  615.         x = sin(a);
  616.         y = cos(a);
  617.         glBegin( GL_LINE_STRIP );
  618.         for (r=innerRadius; r<=outerRadius; r+=dr) {
  619.            glVertex2f( r*x, r*y );
  620.         }
  621.         glEnd();
  622.      }
  623.      break;
  624.       case GLU_POINT:
  625.      glBegin( GL_POINTS );
  626.      for (a=0.0; a<2.0*M_PI; a+=da) {
  627.         x = sin(a);
  628.         y = cos(a);
  629.         for (r=innerRadius; r<=outerRadius; r+=dr) {
  630.            glVertex2f( r*x, r*y );
  631.         }
  632.      }
  633.      glEnd();
  634.      break;
  635.       case GLU_SILHOUETTE:
  636.      if (innerRadius!=0.0) {
  637.         glBegin( GL_LINE_LOOP );
  638.         for (a=0.0; a<2.0*M_PI; a+=da) {
  639.            x = innerRadius * sin(a);
  640.            y = innerRadius * cos(a);
  641.            glVertex2f( x, y );
  642.         }
  643.         glEnd();
  644.      }
  645.      glBegin( GL_LINE_LOOP );
  646.      for (a=0; a<2.0*M_PI; a+=da) {
  647.         x = outerRadius * sin(a);
  648.         y = outerRadius * cos(a);
  649.         glVertex2f( x, y );
  650.      }
  651.      glEnd();
  652.      break;
  653.       default:
  654.          abort();
  655.    }
  656. }
  657.  
  658.  
  659.  
  660. __asm __saveds void APIENTRY gluPartialDiskA(register __a0 void *vargs)
  661. {
  662.     struct gluPartialDiskArgs {
  663.         GLUquadricObj *qobj;
  664.         GLdouble innerRadius;
  665.         GLdouble outerRadius;
  666.         GLint slices;
  667.         GLint loops;
  668.         GLdouble startAngle;
  669.         GLdouble sweepAngle;
  670.     } *args;
  671.  
  672.     args = (struct gluPartialDiskArgs *)vargs;
  673.  
  674.     gluPartialDisk(args->qobj, args->innerRadius, args->outerRadius, args->slices, args->loops, args->startAngle, args->sweepAngle);
  675. }
  676.  
  677.  
  678. __asm __saveds void APIENTRY gluPartialDisk( register __a0 GLUquadricObj *qobj, register __fp0 GLdouble innerRadius,
  679.                                              register __fp1 GLdouble outerRadius, register __d0 GLint slices, register __d1 GLint loops,
  680.                                              register __fp2 GLdouble startAngle, register __fp3 GLdouble sweepAngle )
  681. {
  682.    if (qobj->Normals!=GLU_NONE) {
  683.       if (qobj->Orientation==GLU_OUTSIDE) {
  684.      glNormal3f( 0.0, 0.0, +1.0 );
  685.       }
  686.       else {
  687.      glNormal3f( 0.0, 0.0, -1.0 );
  688.       }
  689.    }
  690.  
  691.    if (qobj->DrawStyle==GLU_POINT) {
  692.       GLint loop, slice;
  693.       GLdouble radius, delta_radius;
  694.       GLdouble angle, delta_angle;
  695.       delta_radius = (outerRadius - innerRadius) / (loops-1);
  696.       delta_angle = DEG_TO_RAD((sweepAngle) / (slices-1));
  697.       glBegin( GL_POINTS );
  698.       radius = innerRadius;
  699.       for (loop=0; loop<loops; loop++) {
  700.      angle = DEG_TO_RAD(startAngle);
  701.      for (slice=0; slice<slices; slice++) {
  702.         glVertex2d( radius * sin(angle), radius * cos(angle) );
  703.         angle += delta_angle;
  704.      }
  705.      radius += delta_radius;
  706.       }
  707.       glEnd();
  708.    }
  709.    else if (qobj->DrawStyle==GLU_LINE) {
  710.       GLint loop, slice;
  711.       GLdouble radius, delta_radius;
  712.       GLdouble angle, delta_angle;
  713.       delta_radius = (outerRadius - innerRadius) / loops;
  714.       delta_angle = DEG_TO_RAD(sweepAngle / slices);
  715.       /* draw rings */
  716.       radius = innerRadius;
  717.       for (loop=0; loop<loops; loop++) {
  718.      angle = DEG_TO_RAD(startAngle);
  719.      glBegin( GL_LINE_STRIP );
  720.      for (slice=0; slice<slices; slice++) {
  721.         glVertex2d( radius * sin(angle), radius * cos(angle) );
  722.         angle += delta_angle;
  723.      }
  724.      glEnd();
  725.      radius += delta_radius;
  726.       }
  727.       /* draw spokes */
  728.       angle = DEG_TO_RAD(startAngle);
  729.       for (slice=0; slice<slices; slice++) {
  730.      radius = innerRadius;
  731.      glBegin( GL_LINE_STRIP );
  732.      for (loop=0; loop<loops; loop++) {
  733.         glVertex2d( radius * sin(angle), radius * cos(angle) );
  734.         radius += delta_radius;
  735.      }
  736.      glEnd();
  737.      angle += delta_angle;
  738.       }
  739.    }
  740.    else if (qobj->DrawStyle==GLU_SILHOUETTE) {
  741.       GLint slice;
  742.       GLdouble angle, delta_angle;
  743.       delta_angle = DEG_TO_RAD(sweepAngle / slices);
  744.       /* draw outer ring */
  745.       glBegin( GL_LINE_STRIP );
  746.       angle = DEG_TO_RAD(startAngle);
  747.       for (slice=0; slice<=slices; slice++) {
  748.      glVertex2d( outerRadius * sin(angle), outerRadius * cos(angle) );
  749.      angle += delta_angle;
  750.       }
  751.       glEnd();
  752.       /* draw inner ring */
  753.       if (innerRadius>0.0) {
  754.      glBegin( GL_LINE_STRIP );
  755.      angle = DEG_TO_RAD(startAngle);
  756.      for (slice=0; slice<slices; slice++) {
  757.         glVertex2d( innerRadius * sin(angle), innerRadius * cos(angle) );
  758.         angle += delta_angle;
  759.      }
  760.      glEnd();
  761.       }
  762.       /* draw spokes */
  763.       if (sweepAngle<360.0) {
  764.      GLdouble stopAngle = startAngle + sweepAngle;
  765.      glBegin( GL_LINES );
  766.      glVertex2d( innerRadius*SIND(startAngle), innerRadius*COSD(startAngle) );
  767.      glVertex2d( outerRadius*SIND(startAngle), outerRadius*COSD(startAngle) );
  768.      glVertex2d( innerRadius*SIND(stopAngle), innerRadius*COSD(stopAngle) );
  769.      glVertex2d( outerRadius*SIND(stopAngle), outerRadius*COSD(stopAngle) );
  770.      glEnd();
  771.       }
  772.    }
  773.    else if (qobj->DrawStyle==GLU_FILL) {
  774.       GLint loop, slice;
  775.       GLdouble radius, delta_radius;
  776.       GLdouble angle, delta_angle;
  777.       delta_radius = (outerRadius - innerRadius) / loops;
  778.       delta_angle = DEG_TO_RAD(sweepAngle / slices);
  779.       radius = innerRadius;
  780.       for (loop=0; loop<loops; loop++) {
  781.      glBegin( GL_QUAD_STRIP );
  782.      angle = DEG_TO_RAD(startAngle);
  783.      for (slice=0; slice<slices; slice++) {
  784.         if (qobj->Orientation==GLU_OUTSIDE) {
  785.            glVertex2d( (radius+delta_radius)*sin(angle),
  786.                (radius+delta_radius)*cos(angle) );
  787.            glVertex2d( radius * sin(angle), radius * cos(angle) );
  788.         }
  789.         else {
  790.            glVertex2d( radius * sin(angle), radius * cos(angle) );
  791.            glVertex2d( (radius+delta_radius)*sin(angle),
  792.                (radius+delta_radius)*cos(angle) );
  793.         }
  794.         angle += delta_angle;
  795.      }
  796.      glEnd();
  797.      radius += delta_radius;
  798.       }
  799.    }
  800. }
  801.  
  802.  
  803.  
  804.